import json
import socket

PORT=6666
SOCKET_BUFFER_SIZE=1024

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(('',PORT))
sock.listen()

ip_map=[]#record mapping between file and ip
#{'file_name':'example.mp4','IP_list':[0.0.0.0,0.0.0.1]}
ip_list=set()#store registered ip

while True:
    conn,addr=sock.accept()
    recv=conn.recv(SOCKET_BUFFER_SIZE)
    recv=json.loads(recv.decode())
    ip_list.add(addr[0])
    print('Message from',addr,':\n',recv)

    if recv['request_type']==1:
        file_list=recv['file_list']
        for file in file_list:#traverse file list uploaded for a peer
            file_num=len(ip_map)#the number of recorded file
            pos=-1
            for i in range(file_num):
                if file['file_name']==ip_map[i]['file_name']:
                    pos=i
                    break
            if pos==-1:#no record before
                ip_map.append({'file_name':file['file_name'],'file_size':file['file_size'],'IP_list':[addr[0]]})
            elif not addr[0] in ip_map[pos]['IP_list']:
                ip_map[pos]['IP_list'].append(addr[0])
        response={'status_code':'200'}
        response=json.dumps(response).encode()
        conn.send(response)
    
    elif not recv['request_type']:
        file_name=recv['file_name']
        pos=-1
        file_num=len(ip_map)
        for i in range(file_num):
            if ip_map[i]['file_name']==file_name:
                pos=i
                break
        if pos==-1:
            response={'status_code':404}
            response=json.dumps(response).encode()
            conn.send(response)
        else:
            response={'status_code':200,'file_size':ip_map[pos]['file_size'],'IP_list':ip_map[pos]['IP_list']}
            response=json.dumps(response).encode()
            print(response)
            conn.send(response)
    elif recv['request_type']==2:
        data={'source':addr[0],'message':recv['message']}
        data=json.dumps(data).encode()
        for ip in ip_list:
            if ip==addr[0]:
                continue

            temp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            temp_sock.connect((ip,PORT))
            temp_sock.send(data)
            temp_sock.close()
    conn.close()
sock.close()